home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / HDUMP.PAK / HDUMP.C next >
C/C++ Source or Header  |  1997-05-06  |  38KB  |  1,143 lines

  1. // Borland C++ - (C) Copyright 1991, 1994 by Borland International
  2.  
  3. //*******************************************************************
  4. //
  5. // program - Hdump.c
  6. // purpose - a windows program to dump a file in hex.
  7. //
  8. //*******************************************************************
  9.  
  10. #define  STRICT
  11. #include <windows.h>
  12. #pragma hdrstop
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <time.h>
  17. #include <bios.h>
  18. #include <ctype.h>
  19. #include <io.h>
  20. #include <dos.h>
  21. #include <dir.h>
  22. #include <windowsx.h>
  23.  
  24. #include "hdump.h"
  25.  
  26. #ifndef __FLAT__          // 16-bit applications are limited to the old
  27. #define MAX_PATH MAXPATH  // path length limit of 80
  28. #endif
  29.  
  30. typedef struct scrollkeys
  31.   {
  32.     WORD wVirtkey;
  33.     int  iMessage;
  34.     WORD wRequest;
  35.   } SCROLLKEYS;
  36.  
  37. SCROLLKEYS key2scroll [] =
  38.   {
  39.     { VK_HOME,  WM_COMMAND, IDM_HOME },
  40.     { VK_END,   WM_VSCROLL, SB_BOTTOM },
  41.     { VK_PRIOR, WM_VSCROLL, SB_PAGEUP },
  42.     { VK_NEXT,  WM_VSCROLL, SB_PAGEDOWN },
  43.     { VK_UP,    WM_VSCROLL, SB_LINEUP },
  44.     { VK_DOWN,  WM_VSCROLL, SB_LINEDOWN },
  45.     { VK_LEFT,  WM_HSCROLL, SB_PAGEUP },
  46.     { VK_RIGHT, WM_HSCROLL, SB_PAGEDOWN }
  47.   };
  48.  
  49. # define NUMKEYS (sizeof key2scroll / sizeof key2scroll[0])
  50.  
  51. // data initialized by first instance
  52. typedef struct tagSETUPDATA
  53.   {
  54.     char   szAppName[10]; // name of application
  55.   } SETUPDATA;
  56.  
  57. SETUPDATA SetUpData;
  58.  
  59. // Data that can be referenced throughout the
  60. // program but not passed to other instances
  61.  
  62. HINSTANCE hInst;                              // hInstance of application
  63. HWND      hWndMain;                           // hWnd of main window
  64.  
  65. int       xChar, yChar, yCharnl;              // character size
  66. int       xClient, yClient;                   // client window size
  67.  
  68. LOGFONT   cursfont;                           // font structure
  69. HFONT     holdsfont;                          // handle of original font
  70. HFONT     hnewsfont;                          // handle of new fixed font
  71.  
  72. // window scroll/paint stuff
  73. int       nVscrollMax, nHscrollMax;           // scroll ranges
  74. int       nVscrollPos, nHscrollPos;           // current scroll positions
  75. int       numlines;                           // number of lines in file
  76. int       maxwidth;                           // width of display format
  77. int       nVscrollInc, nHscrollInc;           // scroll increments
  78. int       nPageMaxLines;                      // max lines on screen
  79.  
  80. // file open dialog stuff
  81. char      szFileSpec[MAX_PATH];               // file spec for initial search
  82. char      szDefExt[5];                        // default extension
  83. char      szFileName[MAX_PATH];               // file name
  84. char      szFilePath[MAX_PATH];               // file path
  85. WORD      wFileAttr;                          // attribute for search
  86. WORD      wStatus;                            // status of search
  87.  
  88. // dump file stuff
  89. char      szFName[MAX_PATH];                  // file to display
  90. FILE     *fh;                                 // handle of open file
  91. LONG      fsize;                              // size of file
  92.  
  93. // function prototypes
  94.  
  95. int      PASCAL        WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  96.                    LPSTR lpszCmdLine, int cmdShow);
  97.  
  98. void                   InitHdump(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  99.                  LPSTR lpszCmdLine, int cmdShow);
  100. void                   InitHdumpFirst(HINSTANCE hInstance);
  101. void                   InitHdumpEvery(HINSTANCE hInstance, int cmdShow);
  102. void                   CloseHdump(void);
  103. BOOL CALLBACK _export About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  104.  
  105. LRESULT CALLBACK  _export HdumpWndProc(HWND hWnd, UINT message,
  106.           WPARAM wParam, LPARAM lParam);
  107.  
  108. void                   SetupScroll(HWND hWnd);
  109. void                   HdumpPaint(HWND hWnd);
  110. char                  *SnapLine(char *szBuf, LPSTR mem, int len,
  111.                 int dwid, char *olbl);
  112.  
  113. int                    DoFileOpenDlg(HINSTANCE hInst, HWND hWnd,
  114.                      char *szFileSpecIn, char *szDefExtIn,
  115.                                      WORD wFileAttrIn,
  116.                                      char *szFilePathOut, char *szFileNameOut);
  117. extern BOOL CALLBACK _export FileOpenDlgProc(HWND hDlg, UINT iMessage,
  118.            WPARAM wParam, LPARAM lParam);
  119.  
  120. //*******************************************************************
  121. // WinMain - Hdump main
  122. //
  123. // paramaters:
  124. //             hInstance     - The instance of this instance of this
  125. //                             application.
  126. //             hPrevInstance - The instance of the previous instance
  127. //                             of this application. This will be 0
  128. //                             if this is the first instance.
  129. //             lpszCmdLine   - A long pointer to the command line that
  130. //                             started this application.
  131. //             cmdShow       - Indicates how the window is to be shown
  132. //                             initially. ie. SW_SHOWNORMAL, SW_HIDE,
  133. //                             SW_MIMIMIZE.
  134. //
  135. // returns:
  136. //             wParam from last message.
  137. //
  138. //*******************************************************************
  139. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  140.            LPSTR lpszCmdLine, int cmdShow)
  141. {
  142.     MSG   msg;
  143.  
  144.     // Go init this application.
  145.     InitHdump(hInstance, hPrevInstance, lpszCmdLine, cmdShow);
  146.  
  147.     // Get and dispatch messages for this applicaton.
  148.     while (GetMessage(&msg, NULL, 0, 0))
  149.     {
  150.     TranslateMessage(&msg);
  151.   DispatchMessage(&msg);
  152.     }
  153.  
  154.     return(msg.wParam);
  155. }
  156.  
  157. #if !defined(__WIN32__)
  158.  
  159. //*******************************************************************
  160. // InitHdumpAdded - done only for added instances of Hdump
  161. //
  162. // paramaters:
  163. //             hPrevInstance - The instance of the previous instance
  164. //                             of this application.
  165. //
  166. //*******************************************************************
  167. void InitHdumpAdded(HINSTANCE hPrevInstance)
  168. {
  169.     // get the results of the initialization of first instance
  170.     GetInstanceData(hPrevInstance, (BYTE*) &SetUpData, sizeof(SETUPDATA));
  171. }
  172. #endif
  173.  
  174. //*******************************************************************
  175.  
  176. //*******************************************************************
  177. // InitHdump - init the Hdump application
  178. //
  179. // paramaters:
  180. //             hInstance     - The instance of this instance of this
  181. //                             application.
  182. //             hPrevInstance - The instance of the previous instance
  183. //                             of this application. This will be 0
  184. //                             if this is the first instance.
  185. //             lpszCmdLine   - A long pointer to the command line that
  186. //                             started this application.
  187. //             cmdShow       - Indicates how the window is to be shown
  188. //                             initially. ie. SW_SHOWNORMAL, SW_HIDE,
  189. //                             SW_MIMIMIZE.
  190. //
  191. //*******************************************************************
  192. #pragma argsused
  193. void InitHdump(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  194.      LPSTR lpszCmdLine, int cmdShow)
  195. {
  196.  
  197.    if (! hPrevInstance)              // if no previous instance, this is first
  198.        InitHdumpFirst(hInstance);
  199. #if !defined(__WIN32__)
  200.    else
  201.       InitHdumpAdded(hPrevInstance);   // this is not first instance
  202. #endif
  203.  
  204.    InitHdumpEvery(hInstance, cmdShow);  // initialization for all instances
  205. }
  206.  
  207. //*******************************************************************
  208. // InitHdumpFirst - done only for first instance of Hdump
  209. //
  210. // paramaters:
  211. //             hInstance     - The instance of this instance of this
  212. //                             application.
  213. //
  214. //*******************************************************************
  215. void InitHdumpFirst(HINSTANCE hInstance)
  216. {
  217.     WNDCLASS wcHdumpClass;
  218.  
  219.     // Get string from resource with application name.
  220.     LoadString(hInstance, IDS_NAME, (LPSTR) SetUpData.szAppName, 10);
  221.  
  222.     // Define the window class for this application.
  223.     wcHdumpClass.lpszClassName = SetUpData.szAppName;
  224.     wcHdumpClass.hInstance     = hInstance;
  225.     wcHdumpClass.lpfnWndProc   = HdumpWndProc;
  226.     wcHdumpClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  227.     wcHdumpClass.hIcon         = LoadIcon(hInstance, SetUpData.szAppName);
  228.     wcHdumpClass.lpszMenuName  = (LPSTR) SetUpData.szAppName;
  229.     wcHdumpClass.hbrBackground = GetStockObject(WHITE_BRUSH);
  230.     wcHdumpClass.style         = CS_HREDRAW | CS_VREDRAW;
  231.     wcHdumpClass.cbClsExtra    = 0;
  232.     wcHdumpClass.cbWndExtra    = 0;
  233.  
  234.     // Register the class
  235.     RegisterClass(&wcHdumpClass);
  236. }
  237.  
  238. //*******************************************************************
  239. // InitHdumpEvery - done for every instance of Hdump
  240. //
  241. // paramaters:
  242. //             hInstance     - The instance of this instance of this
  243. //                             application.
  244. //             cmdShow       - Indicates how the window is to be shown
  245. //                             initially. ie. SW_SHOWNORMAL, SW_HIDE,
  246. //                             SW_MIMIMIZE.
  247. //
  248. //*******************************************************************
  249. void InitHdumpEvery(HINSTANCE hInstance, int cmdShow)
  250. {
  251.     TEXTMETRIC tm;
  252.     HDC        hDC;
  253.  
  254.     hInst = hInstance;       // save for use by window procs
  255.  
  256.     // Create applications main window.
  257.     hWndMain = CreateWindow(
  258.                   SetUpData.szAppName,     // window class name
  259.                   SetUpData.szAppName,     // window title
  260.                   WS_OVERLAPPEDWINDOW |    // type of window
  261.                   WS_HSCROLL |
  262.                   WS_VSCROLL,
  263.                   CW_USEDEFAULT,           // x  window location
  264.                   CW_USEDEFAULT,           // y
  265.                   CW_USEDEFAULT,           // cx and size
  266.                   CW_USEDEFAULT,           // cy
  267.                   NULL,                    // no parent for this window
  268.                   NULL,                    // use the class menu
  269.                   hInstance,               // who created this window
  270.                   NULL                     // no parms to pass on
  271.                   );
  272.  
  273.     // Get the display context.
  274.     hDC = GetDC(hWndMain);
  275.  
  276.     // Build fixed screen font. Needed to display hex formated dump.
  277.     cursfont.lfHeight         =  14;
  278.     cursfont.lfWidth          =  9;
  279.     cursfont.lfEscapement     =  0;
  280.     cursfont.lfOrientation    =  0;
  281.     cursfont.lfWeight         =  FW_NORMAL;
  282.     cursfont.lfItalic         =  FALSE;
  283.     cursfont.lfUnderline      =  FALSE;
  284.     cursfont.lfStrikeOut      =  FALSE;
  285.     cursfont.lfCharSet        =  ANSI_CHARSET;
  286.     cursfont.lfOutPrecision   =  OUT_DEFAULT_PRECIS;
  287.     cursfont.lfClipPrecision  =  CLIP_DEFAULT_PRECIS;
  288.     cursfont.lfQuality        =  DEFAULT_QUALITY;
  289.     cursfont.lfPitchAndFamily =  FIXED_PITCH | FF_DONTCARE;
  290.     strcpy((char *)cursfont.lfFaceName, "System");
  291.  
  292.     hnewsfont = CreateFontIndirect((LPLOGFONT) &cursfont);
  293.  
  294.     // Install the font in the current display context.
  295.     holdsfont = SelectObject(hDC, hnewsfont);
  296.  
  297.     // get text metrics for paint
  298.     GetTextMetrics(hDC, &tm);
  299.     xChar = tm.tmAveCharWidth;
  300.     yChar = tm.tmHeight + tm.tmExternalLeading;
  301.     yCharnl = tm.tmHeight;
  302.  
  303.     // Release the display context.
  304.     ReleaseDC(hWndMain, hDC);
  305.  
  306.     // Update display of main window.
  307.     ShowWindow(hWndMain, cmdShow);
  308.     UpdateWindow(hWndMain);
  309. }
  310.  
  311. //*******************************************************************
  312. // CloseHdump - done at termination of every instance of Hdump
  313. //
  314. //*******************************************************************
  315. void CloseHdump()
  316. {
  317.     DeleteObject(hnewsfont);
  318. }
  319.  
  320. //*******************************************************************
  321. // About - handle about dialog messages
  322. //
  323. // paramaters:
  324. //             hDlg          - The window handle for this message
  325. //             message       - The message number
  326. //             wParam        - The WPARAM parameter for this message
  327. //             lParam        - The LPARAM parameter for this message
  328. //
  329. //*******************************************************************
  330. #pragma argsused
  331. BOOL CALLBACK _export About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  332. {
  333.     if (message == WM_INITDIALOG)
  334.         return(TRUE);
  335.  
  336.     else if (message == WM_COMMAND)
  337.     {
  338.   switch (GET_WM_COMMAND_ID(wParam, lParam))
  339.   {
  340.       case IDOK:
  341.     EndDialog(hDlg, TRUE);
  342.     return(TRUE);
  343.  
  344.       default:
  345.     return(TRUE);
  346.   }
  347.     }
  348.  
  349.     return(FALSE);
  350. }
  351.  
  352. //*******************************************************************
  353.  
  354. //*******************************************************************
  355. // HdumpWndProc - handles messages for this application
  356. //
  357. // paramaters:
  358. //             hWnd          - The window handle for this message
  359. //             message       - The message number
  360. //             wParam        - The WPARAM parameter for this message
  361. //             lParam        - The LPARAM parameter for this message
  362. //
  363. // returns:
  364. //             depends on message.
  365. //
  366. //*******************************************************************
  367. LRESULT CALLBACK _export HdumpWndProc(HWND hWnd, UINT message,
  368.            WPARAM wParam, LPARAM lParam)
  369. {
  370.     static char     sztFilePath[MAX_PATH];  // remember last directory searched
  371.     static char     sztFileExt[5];
  372.     static char     sztFileSpec[MAX_PATH];
  373.     static char     sztFileName[MAX_PATH];
  374.  
  375.     DLGPROC  lpproc;                  // pointer to thunk for dialog box
  376.     char     buf[128];                // temp buffer
  377.     int      i;
  378.     FILE    *fh;
  379.  
  380.     switch (message)
  381.     {
  382.         case WM_CREATE:
  383.             // Start file search at current directory
  384.             getcwd(sztFilePath, sizeof(sztFilePath));
  385.             strcat(sztFilePath, "\\");
  386.             strcpy(sztFileExt, ".*");
  387.             strcpy(sztFileName, "");
  388.  
  389.       return(DefWindowProc(hWnd, message, wParam, lParam));
  390.  
  391.   case WM_COMMAND:
  392.       switch (GET_WM_COMMAND_ID(wParam, lParam))
  393.             {
  394.                 case IDM_QUIT:
  395.                     // User selected Quit on menu
  396.                     PostMessage(hWnd, WM_CLOSE, 0, 0L);
  397.                     break;
  398.  
  399.                 case IDM_HOME:
  400.                     // Used to implement home to topleft from keyboard.
  401.         SendMessage(hWnd, WM_HSCROLL, GET_WM_HSCROLL_MPS (SB_TOP, 0, 0));
  402.         SendMessage(hWnd, WM_VSCROLL, GET_WM_VSCROLL_MPS (SB_TOP, 0, 0));
  403.                     break;
  404.  
  405.     case IDM_ABOUT:
  406.                     // Display about box.
  407.                     lpproc = (DLGPROC)MakeProcInstance((FARPROC)About, hInst);
  408.                     DialogBox(hInst,
  409.                               MAKEINTRESOURCE(ABOUT),
  410.                               hWnd,
  411.                               lpproc);
  412.  
  413.                     #ifndef __FLAT__
  414.                     // required for 16-bit applications only
  415.                     FreeProcInstance((FARPROC)lpproc);
  416.                     #endif
  417.  
  418.                     break;
  419.  
  420.                 case IDM_OPEN:
  421.                     // Setup initial search path for open dialog box.
  422.                     strcpy(sztFileSpec, sztFilePath);
  423.                     strcat(sztFileSpec, "*");
  424.                     strcat(sztFileSpec, sztFileExt);
  425.  
  426.                     // Go ask user to select file to display.
  427.                     if (DoFileOpenDlg(hInst,
  428.                                       hWnd,
  429.                                       sztFileSpec,
  430.                                       sztFileExt,
  431.                                       0x4010, // drives & subdirectories
  432.                                       sztFilePath,
  433.                                       sztFileName))
  434.                     {
  435.                         // If user said OK construct file path/file name
  436.       // to open.
  437.                         strcpy(szFName, sztFilePath);
  438.                         strcat(szFName, sztFileName);
  439.  
  440.                         // Show file name in window caption.
  441.                         sprintf(buf, "hdump - %s", szFName);
  442.                         SetWindowText(hWnd, buf);
  443.  
  444.                         // Determine file size and some display paramaters.
  445.                         fh = fopen(szFName, "r+b");
  446.                         if (fh)
  447.                         {
  448.                             fsize = filelength(fileno(fh));
  449.           numlines = (int) ((fsize + 16L - 1L) / 16L);
  450.                             SnapLine(buf, szFName, 16, 16,NULL); // display width
  451.                             maxwidth = strlen(buf);
  452.                             nVscrollPos = 0;
  453.                             nHscrollPos = 0;
  454.  
  455.                             fclose(fh);
  456.                         }
  457.  
  458.                         else  // if file open failed.
  459.                         {
  460.                             SetWindowText(hWnd, "hdump");
  461.                             numlines = 0;
  462.           maxwidth = 0;
  463.                         }
  464.  
  465.                         // Go setup scroll ranges for this file.
  466.                         SetupScroll(hWnd);
  467.  
  468.                         // Show first part of file.
  469.                         InvalidateRect(hWnd, NULL, TRUE);
  470.                         UpdateWindow(hWnd);
  471.                     }
  472.                     break;
  473.  
  474.                 default:
  475.         break;
  476.           }
  477.           break;
  478.  
  479.         case WM_SIZE:
  480.             // Save size of window client area.
  481.             if (lParam)
  482.               {
  483.                 yClient = HIWORD(lParam);
  484.     xClient = LOWORD(lParam);
  485.  
  486.     yClient = (yClient / yCharnl + 1) * yCharnl;
  487.  
  488.     lParam = MAKELONG(xClient, yClient);
  489.  
  490.     // Go setup scroll ranges and file display area based upon
  491.     // client area size.
  492.     SetupScroll(hWnd);
  493.  
  494.     return(DefWindowProc(hWnd, message, wParam, lParam));
  495.         }
  496.       break;
  497.  
  498.   case WM_VSCROLL:
  499.       // React to the various vertical scroll related actions.
  500.       switch (GET_WM_VSCROLL_CODE(wParam, lParam))
  501.       {
  502.     case SB_TOP:
  503.         nVscrollInc = -nVscrollPos;
  504.         break;
  505.  
  506.     case SB_BOTTOM:
  507.         nVscrollInc = nVscrollMax - nVscrollPos;
  508.         break;
  509.  
  510.     case SB_LINEUP:
  511.         nVscrollInc = -1;
  512.         break;
  513.  
  514.     case SB_LINEDOWN:
  515.         nVscrollInc = 1;
  516.         break;
  517.  
  518.     case SB_PAGEUP:
  519.         nVscrollInc = -max(1, yClient / yChar);
  520.         break;
  521.  
  522.     case SB_PAGEDOWN:
  523.         nVscrollInc = max(1, yClient / yChar);
  524.         break;
  525.  
  526.     case SB_THUMBPOSITION:
  527.         nVscrollInc = GET_WM_VSCROLL_POS(wParam, lParam) - nVscrollPos;
  528.         break;
  529.  
  530.     case SB_THUMBTRACK:
  531.         nVscrollInc = GET_WM_VSCROLL_POS(wParam, lParam) - nVscrollPos;
  532.         break;
  533.  
  534.     default:
  535.         nVscrollInc = 0;
  536.       }
  537.  
  538.       nVscrollInc = max(-nVscrollPos,
  539.             min(nVscrollInc, nVscrollMax - nVscrollPos));
  540.       if (nVscrollInc)
  541.       {
  542.     nVscrollPos += nVscrollInc;
  543.     ScrollWindow(hWnd, 0, -yChar * nVscrollInc, NULL, NULL);
  544.     SetScrollPos(hWnd, SB_VERT, nVscrollPos, TRUE);
  545.     UpdateWindow(hWnd);
  546.       }
  547.       break;
  548.  
  549.   case WM_HSCROLL:
  550.       // React to the various horizontal scroll related actions.
  551.       switch (GET_WM_HSCROLL_CODE(wParam, lParam))
  552.       {
  553.     case SB_LINEUP:
  554.         nHscrollInc = -1;
  555.         break;
  556.  
  557.     case SB_LINEDOWN:
  558.         nHscrollInc = 1;
  559.         break;
  560.  
  561.     case SB_PAGEUP:
  562.         nHscrollInc = -8;
  563.         break;
  564.  
  565.     case SB_PAGEDOWN:
  566.         nHscrollInc = 8;
  567.         break;
  568.  
  569.     case SB_THUMBPOSITION:
  570.         nHscrollInc = GET_WM_HSCROLL_POS(wParam, lParam) - nHscrollPos;
  571.         break;
  572.  
  573.     case SB_THUMBTRACK:
  574.         nHscrollInc = GET_WM_HSCROLL_POS(wParam, lParam) - nHscrollPos;
  575.         break;
  576.  
  577.     default:
  578.         nHscrollInc = 0;
  579.       }
  580.  
  581.       nHscrollInc = max(-nHscrollPos,
  582.             min(nHscrollInc, nHscrollMax - nHscrollPos));
  583.       if (nHscrollInc)
  584.       {
  585.     nHscrollPos += nHscrollInc;
  586.     ScrollWindow(hWnd, -xChar * nHscrollInc, 0, NULL, NULL);
  587.     SetScrollPos(hWnd, SB_HORZ, nHscrollPos, TRUE);
  588.     UpdateWindow(hWnd);
  589.       }
  590.       break;
  591.  
  592.   case WM_KEYDOWN:
  593.       // Translate various keydown messages to appropriate horizontal
  594.       // and vertical scroll actions.
  595.       for (i = 0; i < NUMKEYS; i++)
  596.       {
  597.     if (wParam == key2scroll[i].wVirtkey)
  598.     {
  599.         SendMessage(hWnd, key2scroll[i].iMessage,
  600.         key2scroll[i].wRequest, 0L);
  601.         break;
  602.     }
  603.       }
  604.       break;
  605.  
  606.   case WM_PAINT:
  607.       // Go paint the client area of the window with the appropriate
  608.       // part of the selected file.
  609.       HdumpPaint(hWnd);
  610.       break;
  611.  
  612.   case WM_DESTROY:
  613.       // This is the end if we were closed by a DestroyWindow call.
  614.       CloseHdump();         // take any necessary wrapup action.
  615.       PostQuitMessage(0);   // this is the end...
  616.       break;
  617.  
  618.   case WM_QUERYENDSESSION:
  619.       // If we return TRUE we are saying it's ok with us to end the
  620.       // windows session.
  621.       CloseHdump();         // take any necessary wrapup action.
  622.       return((long) TRUE);  // we agree to end session.
  623.  
  624.   case WM_CLOSE:
  625.       // Tell windows to destroy our window.
  626.       DestroyWindow(hWnd);
  627.       break;
  628.  
  629.   default:
  630.       // Let windows handle all messages we choose to ignore.
  631.       return(DefWindowProc(hWnd, message, wParam, lParam));
  632.     }
  633.  
  634.     return(0L);
  635. }
  636.  
  637. //*******************************************************************
  638. // SetupScroll - setup scroll ranges
  639. //
  640. // Setup the vertical and horizontal scroll ranges and positions
  641. // of the applicatons main window based on:
  642. //
  643. //     numlines - The maximum number of lines to display in a hexdump
  644. //                of the selected file.
  645. //     maxwidth - The width of each line to display as formated for
  646. //                the hexdump.
  647. //
  648. // The resulting variables, nVscrollPos and nPageMaxLines, are used
  649. // by the function HdumpPaint to determine what part of the selected
  650. // file to display in the window.
  651. //
  652. // paramaters:
  653. //             hWnd          - The callers window handle
  654. //
  655. //*******************************************************************
  656. void SetupScroll(HWND hWnd)
  657. {
  658.     // numlines established during open
  659.     nVscrollMax = max(0, numlines - yClient / yChar);
  660.     nVscrollPos = min(nVscrollPos, nVscrollMax);
  661.  
  662.     nHscrollMax = max(0, maxwidth - xClient / xChar);
  663.     nHscrollPos = min(nHscrollPos, nHscrollMax);
  664.  
  665.     SetScrollRange (hWnd, SB_VERT, 0, nVscrollMax, FALSE);
  666.     SetScrollPos   (hWnd, SB_VERT, nVscrollPos, TRUE);
  667.  
  668.     SetScrollRange (hWnd, SB_HORZ, 0, nHscrollMax, FALSE);
  669.     SetScrollPos   (hWnd, SB_HORZ, nHscrollPos, TRUE);
  670.  
  671.     nPageMaxLines = min(numlines, yClient / yChar);
  672. }
  673.  
  674. //*******************************************************************
  675. // HdumpPaint - paint the main window
  676. //
  677. // If a file has been selected, as indicated by numlines being
  678. // greater than 0, this module will read and display a portion
  679. // of the file as determined by the current size and scroll
  680. // position of the window.
  681. //
  682. // paramaters:
  683. //             hWnd          - The callers window handle
  684. //
  685. //*******************************************************************
  686. void HdumpPaint(HWND hWnd)
  687. {
  688.     PAINTSTRUCT  ps;
  689.     HDC          hDC;
  690.     LONG         offset;
  691.     int          tlen;
  692.     int          lpos;
  693.     char         buf[128];
  694.     int          i;
  695.     int          len;
  696.     int          hfile;
  697.     HANDLE       hbuff;
  698.     LPSTR        lpbuff;
  699.     LPSTR        lcp;
  700.  
  701.     BeginPaint(hWnd, (LPPAINTSTRUCT) &ps);
  702.     hDC = ps.hdc;
  703.  
  704.     // Establish fixed font in display context.
  705.     SelectObject(hDC, hnewsfont);
  706.  
  707.     if (numlines)
  708.     {
  709.   // Open the file to display
  710.         // (files should not stay open over multiple windows messages)
  711.         if ((hfile = _lopen(szFName, OF_READ)) != -1)
  712.         {
  713.             // Get a buffer to hold data to fill screen.
  714.             len = nPageMaxLines * 16;
  715.             hbuff = GlobalAlloc(GMEM_MOVEABLE, (DWORD) len);
  716.             if (hbuff)
  717.             {
  718.                 // Lock the buffer to get a pointer to it.
  719.                 lpbuff = GlobalLock(hbuff);
  720.                 if (lpbuff)
  721.                 {
  722.         // Get offset into file to start display.
  723.                     offset = (LONG) nVscrollPos * 16L;
  724.  
  725.                     if (_llseek(hfile, offset, 0) != -1L)
  726.                     {
  727.                         tlen = _lread(hfile, lpbuff, len);
  728.                         if (tlen != -1)
  729.                         {
  730.                             lpos = 0;
  731.                             lcp = lpbuff;
  732.  
  733.                             for (i = nVscrollPos; i < (nVscrollPos + nPageMaxLines); i++)
  734.                             {
  735.         if (tlen > 16)
  736.                                     len = 16;
  737.                                 else
  738.                                     len = tlen;
  739.                                 tlen -= len;
  740.  
  741.                                 SnapLine(buf, lcp, len, 16, (char *) (i * 16));
  742.  
  743.                                 TextOut(hDC,
  744.                                         xChar * (-nHscrollPos + 0),
  745.                                         yChar * lpos++,
  746.                                         buf,
  747.                                         strlen(buf));
  748.  
  749.                                 lcp += 16;
  750.                             }
  751.                         }
  752.                     }
  753.  
  754.                     GlobalUnlock(hbuff);
  755.                 }
  756.  
  757.                 GlobalFree(hbuff);
  758.             }
  759.  
  760.             _lclose(hfile);
  761.   }
  762.     }
  763.  
  764.     EndPaint(hWnd, (LPPAINTSTRUCT) &ps);
  765. }
  766.  
  767. //*******************************************************************
  768. // SnapLine - dump a line of memory
  769. //
  770. // paramaters:
  771. //             szBuf         - buffer to hold result
  772. //             mem           - pointer to memory to format
  773. //             len           - length to format
  774. //             dwid          - max display width (8 or 16 recomended)
  775. //             olbl          - label to put at start of line
  776. //
  777. // returns:
  778. //             A pointer to szBbuf.
  779. //
  780. //*******************************************************************
  781. char *SnapLine(char *szBuf, LPSTR mem, int len, int dwid, char *olbl)
  782. {
  783.     int            i;
  784.     int            j;
  785.     unsigned char  c;
  786.     unsigned char  buff[80];
  787.     unsigned char  tbuf[80];
  788.  
  789.     if (len > dwid)
  790.         len = dwid;
  791.  
  792.     *szBuf = 0;
  793.  
  794.     // Show offset for this line.
  795.     sprintf((char *)tbuf, "%04X  ", olbl);
  796.     strcpy(szBuf, (char *)tbuf);
  797.  
  798.     // Format hex portion of line and save chars for ascii portion
  799.     for (i = 0; i < len; i++)
  800.     {
  801.         c = *mem++;
  802.  
  803.         sprintf((char *)tbuf, "%02X ", c);
  804.         strcat(szBuf, (char *)tbuf);
  805.  
  806.         if (c >= 32 && c < 127)
  807.             buff[i] = c;
  808.         else
  809.             buff[i] = 46;
  810.     }
  811.  
  812.     j = dwid - i;
  813.  
  814.     buff[i] = 0;
  815.  
  816.     // Fill out hex portion of short lines.
  817.     for (i = j; i > 0; i--)
  818.         strcat(szBuf, "   ");
  819.  
  820.     // Add ascii portion to line.
  821.     sprintf((char *)tbuf, " |%s|", (char *)buff);
  822.     strcat(szBuf, (char *)tbuf);
  823.  
  824.     // Fill out end of short lines.
  825.     for (i = j; i > 0; i--)
  826.         strcat(szBuf, " ");
  827.  
  828.     return(szBuf);
  829. }
  830.  
  831. //*******************************************************************
  832. // DoFileOpenDlg - invoke FileOpenDlgProc to get name of file to open
  833. //
  834. // Setup call to FileOpenDlgProc to let user select path/filename
  835. //
  836. // paramaters:
  837. //             hInst         - instance of caller
  838. //             hWnd          - window of caller
  839. //             szFileSpecIn  - file path to search initially
  840. //             szDefExtIn    - file extension search initially
  841. //             wFileAttrIn   - attribute for 'DlgDirList' to use in search
  842. //             szFilePathOut - path of selected file
  843. //             szFileNameOut - name of selected file
  844. //
  845. // returns:
  846. //             1 - if a file selected
  847. //             0 - if file not selected
  848. //
  849. //*******************************************************************
  850. DoFileOpenDlg(HINSTANCE hInst, HWND hWnd,
  851.               char *szFileSpecIn, char *szDefExtIn,
  852.               WORD wFileAttrIn,
  853.               char *szFilePathOut, char *szFileNameOut)
  854. {
  855.     DLGPROC   lpfnFileOpenDlgProc;
  856.     int       iReturn;
  857.  
  858.     // Save starting file spec.
  859.     strcpy(szFileSpec, szFileSpecIn);
  860.     strcpy(szDefExt, szDefExtIn);
  861.     strcpy(szFilePath, szFilePathOut);
  862.     wFileAttr = wFileAttrIn;
  863.  
  864.     lpfnFileOpenDlgProc = (DLGPROC)MakeProcInstance((FARPROC)FileOpenDlgProc, hInst);
  865.  
  866.     iReturn = DialogBox(hInst,
  867.                         MAKEINTRESOURCE(OPENFILE),
  868.                         hWnd,
  869.                         lpfnFileOpenDlgProc);
  870.  
  871.     #ifndef __FLAT__
  872.     // required for 16-bit applications only
  873.     FreeProcInstance((FARPROC)lpfnFileOpenDlgProc);
  874.     #endif
  875.  
  876.     // Return selected file spec.
  877.     strcpy(szFilePathOut, szFilePath);
  878.     strcpy(szFileNameOut, szFileName);
  879.  
  880.     return(iReturn);
  881. }
  882.  
  883. //*******************************************************************
  884. // FileOpenDlgProc - get the name of a file to open
  885. //
  886. // paramaters:
  887. //             hDlg          - The window handle of this dialog box
  888. //             message       - The message number
  889. //             wParam        - The WPARAM parameter for this message
  890. //             lParam        - The LPARAM parameter for this message
  891. //
  892. // returns:
  893. //             depends on message.
  894. //
  895. //*******************************************************************
  896. BOOL CALLBACK _export FileOpenDlgProc(HWND hDlg, UINT iMessage,
  897.         WPARAM wParam, LPARAM lParam)
  898. {
  899.     static char   curpath[MAX_PATH];
  900.     char          tempDir[MAX_PATH], *tempStr = NULL;
  901.     unsigned      attrib;
  902.     char          cLastChar;
  903.     int           nLen;
  904.      struct ffblk  fileinfo;
  905.      #ifndef __FLAT__
  906.      int           tempDirNum;
  907.      #endif
  908.  
  909.     switch (iMessage)
  910.     {
  911.         case WM_INITDIALOG:
  912.             // Save current working directory (will be restored on exit)
  913.             getcwd(curpath, sizeof(curpath));
  914.  
  915.             SendDlgItemMessage(hDlg, IDD_FNAME, EM_LIMITTEXT, 80, 0L);
  916.  
  917.             // Fill list box with files from starting file spec.
  918.             DlgDirList(hDlg,
  919.                        szFileSpec,
  920.                        IDD_FLIST,
  921.                        IDD_FPATH,
  922.                        wFileAttr);
  923.  
  924.       // Save starting file spec.
  925.       SetDlgItemText(hDlg, IDD_FNAME, szFileSpec);
  926.       return(TRUE);
  927.  
  928.   case WM_COMMAND:
  929.       switch (GET_WM_COMMAND_ID(wParam, lParam))
  930.       {
  931.     case IDD_FLIST:
  932.         switch (GET_WM_COMMAND_CMD(wParam, lParam))
  933.         {
  934.       case LBN_SELCHANGE:
  935.           if (DlgDirSelectEx(hDlg, szFileName, sizeof (szFileName), IDD_FLIST))
  936.         strcat(szFileName, szFileSpec);
  937.           SetDlgItemText(hDlg, IDD_FNAME, szFileName);
  938.           break;
  939.  
  940.       case LBN_DBLCLK:
  941.           if (DlgDirSelectEx(hDlg, szFileName, sizeof (szFileName), IDD_FLIST))
  942.           {
  943.         SendMessage(hDlg, WM_COMMAND,
  944.               GET_WM_COMMAND_MPS (IDOK, 0, 0));
  945.           }
  946.           else
  947.           {
  948.         SetDlgItemText(hDlg, IDD_FNAME, szFileName);
  949.         SendMessage(hDlg, WM_COMMAND,
  950.               GET_WM_COMMAND_MPS (IDOK, 0, 0));
  951.           }
  952.           break;
  953.         }
  954.         break;
  955.  
  956.     case IDD_FNAME:
  957.         if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  958.         {
  959.       EnableWindow(GetDlgItem(hDlg, IDOK),
  960.              (BOOL) SendMessage((HWND)lParam,
  961.               WM_GETTEXTLENGTH, 0, 0L));
  962.         }
  963.         break;
  964.  
  965.                 case IDOK:
  966.         GetDlgItemText(hDlg, IDD_FNAME, szFileName, sizeof(szFileName));
  967.  
  968.         nLen  = strlen(szFileName);
  969.  
  970.         // Save new spec. & directory
  971.         strcpy(tempDir, szFileName);
  972.  
  973.         if (!strchr(tempDir, '*')) // GetFileAttributes does not like wildcards
  974.         {
  975. #ifdef __FLAT__
  976.              // GetFileAttributes does not like bogus drive letters
  977.              if (tempDir[1] != ':')
  978.              {
  979.                   attrib = GetFileAttributes( (LPCTSTR) tempDir );
  980.              }
  981.              else  // need to check drive letter
  982.              {
  983.                  tempDir[1] = 0;
  984.                  strcat(tempDir +1, ":\\");
  985.                  if (GetDriveType(tempDir) != 1)  // drive letter valid
  986.                  {
  987.                       strcpy(tempDir, szFileName);
  988.                       attrib = GetFileAttributes( (LPCTSTR) tempDir );
  989.                  }
  990.                  else  // drive letter invalid
  991.                  {
  992.                        MessageBox(NULL, "Invalid drive lettter specified.",
  993.                           "HDUMP", MB_OK | MB_TASKMODAL);
  994.                        strcpy(szFileName, szFilePath);
  995.                        strcat(szFileName, "*.*");
  996.                        SetDlgItemText(hDlg, IDD_FNAME, "*.*");
  997.                        strcpy(tempDir, szFileName);
  998.                        nLen = strlen(szFileName);
  999.                        attrib = -1;
  1000.                  }
  1001.              }
  1002. #else
  1003.              // _dos_getfileattr does not like bogus drive letters either
  1004.              if (tempDir[1] != ':')
  1005.              {
  1006.                   _dos_getfileattr(tempDir, &attrib);
  1007.              }
  1008.              else  // need to check drive letter
  1009.              {
  1010.                  strupr(tempDir);
  1011.                  tempDirNum = tempDir[0] - 'A';
  1012.                  if (GetDriveType(tempDirNum) != 0)  // drive letter valid
  1013.                  {
  1014.                       strcpy(tempDir, szFileName);
  1015.                       // _dos_getfileattr doesn't like paths ending in ':'
  1016.                       if (strchr(tempDir, ':')[1] == 0)
  1017.                            strcat(tempDir, ".");
  1018.                       _dos_getfileattr(tempDir, &attrib);
  1019.                  }
  1020.                  else  // drive letter invalid
  1021.                  {
  1022.                        MessageBox(NULL, "Invalid drive lettter specified.",
  1023.                           "HDUMP", MB_OK | MB_TASKMODAL);
  1024.                        strcpy(szFileName, szFilePath);
  1025.                        strcat(szFileName, "*.*");
  1026.                        SetDlgItemText(hDlg, IDD_FNAME, "*.*");
  1027.                        strcpy(tempDir, szFileName);
  1028.                        nLen = strlen(szFileName);
  1029.                        attrib = -1;
  1030.                  }
  1031.              }
  1032. #endif
  1033.         }
  1034.         else
  1035.              attrib = -1;
  1036.  
  1037.         if(!(attrib == _A_SUBDIR) )
  1038.         {
  1039.          tempStr = strrchr(tempDir, '\\');
  1040.          if(tempStr)
  1041.             tempStr[1] = 0;
  1042.         }
  1043.         if(tempStr || (attrib == _A_SUBDIR))
  1044.         {
  1045.            if (tempDir[1] == ':')
  1046.                 strcpy(szFilePath, tempDir);
  1047.            else
  1048.                 strcat(szFilePath, tempDir);
  1049.         }
  1050.  
  1051.         cLastChar = *AnsiPrev(szFileName, szFileName + nLen);
  1052.         if (cLastChar == '\\' || cLastChar == ':')
  1053.         {
  1054.          strcpy(szFilePath, szFileName);
  1055.          chdir(szFilePath);
  1056.          SetDlgItemText(hDlg, IDD_FPATH, szFilePath);
  1057.          strcat(szFileName, szFileSpec);
  1058.         }
  1059.         if( szFileName[ 1 ] == ':' && 
  1060.             strcmp( "*.*", &szFileName[ 2 ] ) == 0 )
  1061.         {
  1062.          strcpy( szFilePath, szFileName );
  1063.          szFilePath[ 2 ] = 0x0;
  1064.          chdir(szFilePath);
  1065.          SetDlgItemText(hDlg, IDD_FPATH, szFilePath);
  1066.         }
  1067.  
  1068.         if (strchr(szFileName, '*') || strchr(szFileName, '?'))
  1069.         {
  1070.          if (DlgDirList(hDlg, szFileName, IDD_FLIST, IDD_FPATH, wFileAttr))
  1071.          {
  1072.             strcpy(szFileSpec, szFileName);
  1073.             SetDlgItemText(hDlg, IDD_FNAME, szFileSpec);
  1074.          }
  1075.          else
  1076.             MessageBeep(0);
  1077.          break;
  1078.         }
  1079.  
  1080.         // Fill list with new spec.
  1081.         if (DlgDirList(hDlg, szFileName, IDD_FLIST, IDD_FPATH, wFileAttr))
  1082.         {
  1083.          strcpy(szFileSpec, szFileName);
  1084.          SetDlgItemText(hDlg, IDD_FNAME, szFileSpec);
  1085.          break;
  1086.         }
  1087.  
  1088.         // Since we fell through, szFileName was not a search path.
  1089.         szFileName[nLen] = '\0';
  1090.  
  1091.         // Make sure file exists.
  1092.         if (findfirst(szFileName, &fileinfo, 0))
  1093.         {
  1094.          strcat(szFileName, szDefExt);
  1095.  
  1096.          // Make sure file exists.
  1097.          if (findfirst(szFileName, &fileinfo, 0))
  1098.          {
  1099.             // No, beep and break.
  1100.             MessageBeep(0);
  1101.             break;
  1102.          }
  1103.         }
  1104.  
  1105.         strupr(szFilePath);
  1106.         nLen = strlen( szFilePath ) - 1;
  1107.         if (szFilePath[ nLen ] != '\\' &&
  1108.             szFilePath[ nLen ] != ':' )
  1109.                strcat(szFilePath, "\\");
  1110.  
  1111.         // Return selected file name.
  1112.         strcpy(szFileName, fileinfo.ff_name);
  1113.  
  1114.         // Restore current working directory.
  1115.         chdir(curpath);
  1116.  
  1117.         // Terminate this dialog box.
  1118.         EndDialog(hDlg, TRUE);
  1119.                     break;
  1120.  
  1121.                 case IDCANCEL:
  1122.                     // Restore current working directory
  1123.                     chdir(curpath);
  1124.  
  1125.                     // Terminate this dialog box.
  1126.                     EndDialog(hDlg, FALSE);
  1127.                     break;
  1128.  
  1129.     default:
  1130.                     return(FALSE);
  1131.       }
  1132.             break;
  1133.  
  1134.         default:
  1135.             return(FALSE);
  1136.     }
  1137.  
  1138.     return(TRUE);
  1139. }
  1140.  
  1141. //*******************************************************************
  1142.  
  1143.